package com.yc.aspects;


import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @ClassName MyAspects
 * @since: 2023/8/1 09:58
 * @auth: kirito
 * @description:
 **/
@Component
@Aspect
public class MyAspects {
    /*切入点表达式： 正则表达式  筛选  目标类中哪些方法增强
     *    * :
     *    ..:代表0或n
     * */
    @Pointcut("execution(* com.yc.biz.*.make*(..))")
    private void a() {}

    @Before("a()")
    public void recordTime() {
        Date date = new Date();
        System.out.println("*******下单时间：" + date);
    }

    @AfterReturning("a()")
    public void sendEmail() {
        System.out.println("调用数据库查询此下单用户的email，包装信息发送消息到中间件 kafka/mq");
    }

    @AfterReturning("a()")
    public void recordParams(JoinPoint jp) {
        //记录连接点 make*（） 中的参数信息 make*（）成为join point
        //从jp中取出方法的信息
        System.out.println("增强的方法：" + jp.getStaticPart());
        System.out.println("增强的目标类：" + jp.getStaticPart());
        System.out.println("参数：");
        Object[] params = jp.getArgs();
        for (Object o : params) {
            System.out.println(o);
        }
    }

    @AfterThrowing(pointcut = "a()",
            throwing = "ex")
    public void recordException(JoinPoint jp, RuntimeException ex) {
        System.out.println("*******异常了**********");
        System.out.println(ex.getMessage());
        System.out.println(jp.getArgs()[0] + "\t" + jp.getArgs()[1]);
        System.out.println("**********************");

    }

    @Pointcut("execution(* com.yc.biz.*.findOrder(String))")
    private void b() {}

    private Map<String, Long> map = new ConcurrentHashMap<String, Long>();

    //统计每个商品被查询的次数
    @AfterReturning("b()")
    public void recordPnameCOunt(JoinPoint jp) {
        Object[] objs = jp.getArgs();
        String pname = (String) objs[0];
        Long num = 1L;
        if (map.containsKey(pname)) {
            num = map.get(pname);
            num++;
        }
        map.put(pname, num);
        System.out.println("统计结果：" + map);
    }
    @Pointcut("execution(int com.yc.biz.*.findPid(String))")
    private void c() {}
    private Map<String, Long> map2 = new ConcurrentHashMap<String, Long>();

    @AfterReturning(pointcut = "c()", returning = "retValue")
    private void recordPnameCount2(JoinPoint jp, int retValue) {
        Object[] objs = jp.getArgs();
        String pname = (String) objs[0];
        Long num = 1L;
        if (map2.containsKey(pname)) {
            num = map2.get(pname);
            num++;
        }
        map2.put(pname + "_" + retValue, num);
        System.out.println("统计结果：" + map2);
    }
    //统计查询时长
    @Pointcut("execution(int com.yc.biz.*.find*(..))")
    private void d() {}

    @Around("d()")
    private Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
        //pjp就是被调用的方法find*
        long start = System.currentTimeMillis();
        Object retVal = pjp.proceed(); //返回值 find*
        long end = System.currentTimeMillis();
        System.out.println("方法执行时长为：" + (end-start));
        return retVal;
    }


}
